#ifndef CVCAMERA_H
#define CVCAMERA_H

#include <iostream>
#include <ctime>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <sstream>
#include <vector>

namespace bottracker {
    using std::cout;
    using std::cerr;
    using std::endl;
    using std::string;
    using std::vector;
    using std::stringstream;

class CvCamera
{
    friend class CvCalibrateGUI;        ///<Zaprzyjaźnienie konieczne do współdziałania GUI i logiki aplikacji
    public:
    /** \brief konstruktor
     *
     * @param FrameSize rozmiar klatki
     * @param InnerVertexes ilość wewnętrznych wierzchołków wzorca
     */
        CvCamera( CvSize FrameSize, CvSize InnerVertexes );
    /** \brief destruktor
     */
        ~CvCamera();
    /** \brief inicjalizacja wierzchołków wzorca 3D
     *
     * @param SquareSize rozmiar kwadratu w milimentrach
     */
        inline void init_object_points( int SquareSize );
    /** \brief zapisuje uzyskane dane na dysku
     *
     * save_data wejściowe parametry i uzyskane dane do pliku XML
     * @param FileName nazwa wyjściowego pliku z danymi
     * @return true w przypadku sukcesu, false w przeciwnym wypadku
     */
        bool save_data( const char* Filename );
    /** \brief pobiera kolejna klatekę ze strumienia
     *
     * Pobiera kolejną klatkę ze strumienia i kopiuje ją do pamięci.
     * @param frame klatka do skopiowania
     */
        bool get_frame( IplImage* frame );
    /** \brief kalibracja kamery
     *
     * Funkcja dokonująca kalibracji kamery w oparciu o algorytm
	 * <b>Zhengyou Zhang</b> opisany w dokumencie
	 * <a href=http://research.microsoft.com/~zhang/calib/ >A Flexible New Technique for Camera Calibration</a>
	 */
        bool calibrate( int SquareSize );
    private:
        static const int NFRAMES = 10;    ///< Rezerwacja miejsca dla początkowych klatek
        CvSize pm_ImageSize;              ///< Rozmiar klatki w pikselach
        CvSize pm_BoardSize;              ///< Ilość wewnętrznych woerzchołków we wzorcu kalibracyjnym
        vector<IplImage*> pm_Patterns;    ///< Pobrane wzorce kalibracyjne
        int pm_Grabbed;                   ///< Ilość pobranych wzorców
        int pm_CalibPoints;               ///< Ilość punktów kalibracynych, po prostu pm_BoardSize.width*pm_BoardSize.height
        CvMat* pm_ObjectPoints;	          ///< Współrzędne wierzchołków wzorca 3D (zadane)
        CvMat* pm_ImagePoints;	          ///< Współrzędne wierzchołków wzorca 2D (rzeczywiste)
        CvMat* pm_CornersFound;	          ///< Ilość wierzchołków znaleziona w każdej iteracji
        CvMat* pm_IntrinsicMat;	          ///< Macierz A[3x3] parametrów kamery
        CvMat* pm_DistCoeffs;	          ///< Macierz zniekształceń D[1x4] lub D[4x1]
        CvMat* pm_RotVector;	          ///< Wektor rotacji
        CvMat* pm_TransVector;	          ///< Wektor translacji
};


}
#endif // CVCAMERA_H
